package com.bq.server.handler;

import com.bq.server.utils.EncryptUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.springframework.util.StringUtils;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * AES加密 typehandler
 * @author: ChenSH
 * @date: Create by in 09:52 2019-03-13
 */
@Slf4j
public class AESTypeHandler extends BaseTypeHandler<String> {

    private final String key;

    public AESTypeHandler(String key) {
        this.key = key;
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
            throws SQLException {
        try {
            ps.setString(i, EncryptUtils.aesEncrypt(parameter, key));
        } catch (Exception e) {
            log.error("{},加密错误:{}", parameter, e.getMessage(), e);
            throw new SQLException(e);
        }
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName)
            throws SQLException {

        return decrypt(rs.getString(columnName), columnName);
    }

    private String decrypt(String value, String columnName) {
        try {
            if (StringUtils.isEmpty(value)) {
                return value;
            }
            return EncryptUtils.aesDecrypt(value, key);
        } catch (Exception e) {
            log.error("{}={},解密错误:{}", columnName, value, e.getMessage(), e);
            return value;
        }
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex)
            throws SQLException {
        String columnName = rs.getMetaData().getColumnName(columnIndex);
        return decrypt(rs.getString(columnIndex), columnName);
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex)
            throws SQLException {
        String columnName = cs.getMetaData().getColumnName(columnIndex);
        return decrypt(cs.getString(columnIndex), columnName);
    }
}
